import pygame
import sys
import random

# 初始化Pygame
pygame.init()

# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
GRID_SIZE = 20
GRID_WIDTH = SCREEN_WIDTH // GRID_SIZE
GRID_HEIGHT = SCREEN_HEIGHT // GRID_SIZE

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
LIGHT_GREEN = (100, 255, 100)
DARK_GREEN = (0, 200, 0)
BORDER_COLOR = (50, 50, 50)

# 方向常量
UP = (0, -1)
DOWN = (0, 1)
LEFT = (-1, 0)
RIGHT = (1, 0)

# 创建游戏窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("贪吃蛇游戏")

# 游戏时钟
clock = pygame.time.Clock()
BASE_FPS = 10
FPS = BASE_FPS

# 游戏状态
START_SCREEN = 0
GAME_RUNNING = 1
GAME_OVER = 2

# 初始化字体
pygame.font.init()
font = pygame.font.SysFont("SimHei", 30)

# 食物类
class Food:
    def __init__(self):
        self.position = (0, 0)
        self.color = RED
        self.randomize_position()
        self.blink_state = True
        self.blink_timer = 0
    
    def randomize_position(self):
        # 随机生成食物位置
        self.position = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1))
        self.blink_state = True
        self.blink_timer = 0
    
    def update(self):
        # 使食物闪烁以增加视觉效果
        self.blink_timer += 1
        if self.blink_timer % 10 == 0:
            self.blink_state = not self.blink_state
    
    def draw(self, surface):
        # 绘制食物
        rect = pygame.Rect((self.position[0] * GRID_SIZE, self.position[1] * GRID_SIZE), (GRID_SIZE, GRID_SIZE))
        # 根据闪烁状态调整颜色亮度
        color = self.color if self.blink_state else (200, 0, 0)
        pygame.draw.rect(surface, color, rect)
        pygame.draw.rect(surface, WHITE, rect, 1)

# 贪吃蛇类
class Snake:
    def __init__(self):
        self.reset()
    
    def reset(self):
        # 初始位置和长度
        self.body = [(GRID_WIDTH // 2, GRID_HEIGHT // 2)]
        self.direction = RIGHT
        self.next_direction = RIGHT
        self.grow = False  # 标记是否需要增长
        self.grow_amount = 0  # 连续增长的数量，用于吃到食物后的视觉效果
    
    def change_direction(self, new_direction):
        # 确保蛇不能直接反向移动
        if (new_direction[0] * -1, new_direction[1] * -1) != self.direction:
            self.next_direction = new_direction
    
    def move(self):
        # 更新方向
        self.direction = self.next_direction
        
        # 获取蛇头位置
        head = self.body[0]
        x, y = self.direction
        
        # 计算新的蛇头位置
        new_head = ((head[0] + x) % GRID_WIDTH, (head[1] + y) % GRID_HEIGHT)
        
        # 添加新的头部
        self.body.insert(0, new_head)
        
        # 如果不需要增长，则移除尾部
        if self.grow_amount > 0:
            self.grow_amount -= 1
        else:
            self.body.pop()
    
    def grow_snake(self, amount=1):
        self.grow_amount += amount
    
    def draw(self, surface):
        # 绘制蛇的身体，使用渐变效果
        for i, (x, y) in enumerate(self.body):
            rect = pygame.Rect((x * GRID_SIZE, y * GRID_SIZE), (GRID_SIZE, GRID_SIZE))
            
            # 头部特殊处理
            if i == 0:
                pygame.draw.rect(surface, BLUE, rect)
                # 绘制眼睛，根据方向调整位置
                eye_size = GRID_SIZE // 5
                if self.direction == UP:
                    eye1_pos = (x * GRID_SIZE + GRID_SIZE // 4, y * GRID_SIZE + GRID_SIZE // 4)
                    eye2_pos = (x * GRID_SIZE + GRID_SIZE * 3 // 4 - eye_size, y * GRID_SIZE + GRID_SIZE // 4)
                elif self.direction == DOWN:
                    eye1_pos = (x * GRID_SIZE + GRID_SIZE // 4, y * GRID_SIZE + GRID_SIZE * 3 // 4 - eye_size)
                    eye2_pos = (x * GRID_SIZE + GRID_SIZE * 3 // 4 - eye_size, y * GRID_SIZE + GRID_SIZE * 3 // 4 - eye_size)
                elif self.direction == LEFT:
                    eye1_pos = (x * GRID_SIZE + GRID_SIZE // 4, y * GRID_SIZE + GRID_SIZE // 4)
                    eye2_pos = (x * GRID_SIZE + GRID_SIZE // 4, y * GRID_SIZE + GRID_SIZE * 3 // 4 - eye_size)
                else:  # RIGHT
                    eye1_pos = (x * GRID_SIZE + GRID_SIZE * 3 // 4 - eye_size, y * GRID_SIZE + GRID_SIZE // 4)
                    eye2_pos = (x * GRID_SIZE + GRID_SIZE * 3 // 4 - eye_size, y * GRID_SIZE + GRID_SIZE * 3 // 4 - eye_size)
                
                pygame.draw.rect(surface, WHITE, (eye1_pos[0], eye1_pos[1], eye_size, eye_size))
                pygame.draw.rect(surface, WHITE, (eye2_pos[0], eye2_pos[1], eye_size, eye_size))
            else:
                # 身体部分使用渐变颜色
                # 越靠近头部颜色越亮
                intensity = max(0, 255 - (i * 10))
                body_color = (0, intensity, 0)
                pygame.draw.rect(surface, body_color, rect)
            
            # 添加边框
            pygame.draw.rect(surface, WHITE, rect, 1)
    
    def check_collision(self):
        # 检测是否撞到自己
        head = self.body[0]
        return head in self.body[1:]

# 创建游戏对象
food = Food()
snake = Snake()
score = 0
game_over = False
paused = False
game_state = START_SCREEN
max_score = 0  # 记录最高分

# 绘制游戏边框
def draw_border(surface):
    pygame.draw.rect(surface, BORDER_COLOR, (0, 0, SCREEN_WIDTH, GRID_SIZE))
    pygame.draw.rect(surface, BORDER_COLOR, (0, SCREEN_HEIGHT - GRID_SIZE, SCREEN_WIDTH, GRID_SIZE))
    pygame.draw.rect(surface, BORDER_COLOR, (0, 0, GRID_SIZE, SCREEN_HEIGHT))
    pygame.draw.rect(surface, BORDER_COLOR, (SCREEN_WIDTH - GRID_SIZE, 0, GRID_SIZE, SCREEN_HEIGHT))

# 检测蛇是否吃到食物
def check_food_collision():
    global score
    if snake.body[0] == food.position:
        # 吃到食物，设置增长标记并重新生成食物位置
        snake.grow_snake(1)
        # 增加分数
        score += 10
        # 更新最高分
        update_max_score()
        # 根据分数调整游戏难度
        adjust_game_speed()
        # 确保食物不会生成在蛇身上
        while food.position in snake.body:
            food.randomize_position()
        return True
    return False

# 更新最高分
def update_max_score():
    global max_score
    if score > max_score:
        max_score = score

# 根据分数调整游戏速度
def adjust_game_speed():
    global FPS
    FPS = BASE_FPS + (score // 50)  # 每得50分，速度加1
    # 设置速度上限
    FPS = min(FPS, BASE_FPS * 2)  # 最大速度为初始速度的2倍

# 显示最高分
def draw_max_score(surface):
    max_score_text = font.render(f"最高分: {max_score}", True, WHITE)
    surface.blit(max_score_text, (10, 50))

# 显示开始界面
def draw_start_screen(surface):
    title_text = font.render("贪吃蛇游戏", True, GREEN)
    start_text = font.render("按空格键开始游戏", True, WHITE)
    controls_text = font.render("使用方向键控制移动，空格键暂停", True, WHITE)
    
    title_rect = title_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 - 60))
    start_rect = start_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2))
    controls_rect = controls_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 60))
    
    surface.blit(title_text, title_rect)
    surface.blit(start_text, start_rect)
    surface.blit(controls_text, controls_rect)

# 显示得分
def draw_score(surface):
    score_text = font.render(f"分数: {score}", True, WHITE)
    surface.blit(score_text, (10, 10))

# 显示游戏结束信息
def draw_game_over(surface):
    game_over_text = font.render("游戏结束!", True, RED)
    restart_text = font.render("按R键重新开始，按ESC键退出", True, WHITE)
    
    # 计算文本位置使其居中
    game_over_rect = game_over_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 - 30))
    restart_rect = restart_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 30))
    
    surface.blit(game_over_text, game_over_rect)
    surface.blit(restart_text, restart_rect)

# 显示暂停信息
def draw_pause(surface):
    pause_text = font.render("游戏暂停", True, WHITE)
    continue_text = font.render("按空格键继续，按ESC键退出", True, WHITE)
    
    # 计算文本位置使其居中
    pause_rect = pause_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 - 30))
    continue_rect = continue_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 30))
    
    surface.blit(pause_text, pause_rect)
    surface.blit(continue_text, continue_rect)

# 重置游戏
def reset_game():
    # 声明所有需要修改的全局变量
    global score, game_over, paused, FPS
    score = 0
    game_over = False
    paused = False
    FPS = BASE_FPS  # 重置游戏速度
    snake.reset()
    food.randomize_position()
    # 确保食物不会生成在蛇身上
    while food.position in snake.body:
        food.randomize_position()

def main():
    # 声明全局变量
    global game_state, paused, game_over, running, score, FPS, max_score
    
    running = True
    
    # 主游戏循环
    while running:
        # 处理事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    running = False
                elif event.key == pygame.K_SPACE:
                    if game_state == START_SCREEN:
                        # 从开始界面进入游戏
                        reset_game()
                        game_state = GAME_RUNNING
                    elif game_state == GAME_RUNNING:
                        # 切换暂停状态
                        paused = not paused
                elif game_state == GAME_RUNNING and not paused:
                    if event.key == pygame.K_UP:
                        snake.change_direction(UP)
                    elif event.key == pygame.K_DOWN:
                        snake.change_direction(DOWN)
                    elif event.key == pygame.K_LEFT:
                        snake.change_direction(LEFT)
                    elif event.key == pygame.K_RIGHT:
                        snake.change_direction(RIGHT)
                elif game_state == GAME_OVER and event.key == pygame.K_r:
                    # 游戏结束后重新开始
                    reset_game()
                    game_state = GAME_RUNNING
        
        # 根据游戏状态更新
        if game_state == GAME_RUNNING:
            if not paused and not game_over:
                # 移动蛇
                snake.move()
                # 更新食物状态
                food.update()
                # 检测食物碰撞
                check_food_collision()
                # 检测游戏结束条件
                if snake.check_collision():
                    game_over = True
                    game_state = GAME_OVER
        
        # 清屏
        screen.fill(BLACK)
        
        # 根据游戏状态绘制
        if game_state == START_SCREEN:
            draw_start_screen(screen)
        elif game_state == GAME_RUNNING:
            # 绘制游戏元素
            draw_border(screen)
            food.draw(screen)
            snake.draw(screen)
            draw_score(screen)
            draw_max_score(screen)
            
            # 如果游戏暂停，显示暂停信息
            if paused:
                draw_pause(screen)
        elif game_state == GAME_OVER:
            # 绘制游戏元素和游戏结束信息
            draw_border(screen)
            food.draw(screen)
            snake.draw(screen)
            draw_score(screen)
            draw_max_score(screen)
            draw_game_over(screen)
        
        # 更新显示
        pygame.display.flip()
        
        # 控制帧率
        clock.tick(FPS)

# 调用主函数
if __name__ == "__main__":
    main()
    # 退出游戏
    pygame.quit()
    sys.exit()